package com.hmall.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.hmall.common.PageBean;
import com.hmall.feign.client.ItemClient;
import com.hmall.item.pojo.Item;
import com.hmall.search.constants.ItemConstants;
import com.hmall.search.dto.SearchDto;
import com.hmall.search.service.SearchService;
import lombok.SneakyThrows;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service //将类交给Spring框架管理
public class SearchServiceImpl implements SearchService {

    @Autowired
    ItemClient itemClient;
    //注入es核心对象
    @Autowired
    RestHighLevelClient client;

    @Override
    public void mysql2ES() throws IOException {
        //1. 先判断item索引库是否存在
        GetIndexRequest getIndexRequest = new GetIndexRequest("item");
        boolean exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);


        //2. 如果不存在，就创建索引库
        if (!exists) {
            //1. 创建索引请求对象
            CreateIndexRequest request = new CreateIndexRequest("item");
            //设置索引的字段类型
            request.source(ItemConstants.JSON, XContentType.JSON);

            //2. 执行请求对象
            client.indices().create(request, RequestOptions.DEFAULT);
        }


        //项目启动时执行（只执行一次）
        //1. 获取到mysql数据库中的数据（通过feign接口）
        PageBean<Item> pageBean = itemClient.queryItemByPage(1, 1000);
        List<Item> list = pageBean.getList();

        //2. 遍历集合，将每一个Item对象添加到es中
        for (Item item : list) {
            //1. 创建文档请求对象
            IndexRequest request = new IndexRequest("item");
            //设置索引的字段类型
            request.id(String.valueOf(item.getId()));
            request.source(JSON.toJSONString(item), XContentType.JSON);

            //2. 执行请求对象
            client.index(request, RequestOptions.DEFAULT);
        }
    }

    @Override
    @SneakyThrows //捕获异常
    public PageBean<Item> search(SearchDto dto) {
        //1. 创建搜索请求对象
        SearchRequest request = new SearchRequest("item");

        //2. 通过request对象设置查询条件
        BoolQueryBuilder boolQuery = new BoolQueryBuilder();

        boolQuery.must(QueryBuilders.matchAllQuery()); //查询所有

        request.source()
                .query(boolQuery)
                .from((dto.getPage() - 1) * dto.getSize())   //第一页：0   第二页：5  第三页：15
                .size(dto.getSize());

        //TODO 封装各种各样的查询条件
        //TODO 封装各种各样的查询条件
        //TODO 封装各种各样的查询条件

        //3. 通过client对象，执行
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        //4. 处理结果
        SearchHit[] hits = response.getHits().getHits();

        //map：映射，将A->B    SearchHit->Item
        List<Item> list = Arrays.stream(hits).map(searchHit -> {
            return JSON.parseObject(searchHit.getSourceAsString(), Item.class);
        }).collect(Collectors.toList());

        return new PageBean<>(response.getHits().getTotalHits().value, list);
    }
}